// PGM 平台通用JavaScript工具

/**
 * 全局工具对象
 */
window.PGMUtils = {
    
    /**
     * 显示通知消息
     */
    showNotification: function(message, type = 'info', duration = 3000) {
        // 创建通知元素
        const notification = document.createElement('div');
        notification.className = `alert alert-${type} alert-dismissible fade show position-fixed`;
        notification.style.cssText = `
            top: 20px;
            right: 20px;
            z-index: 9999;
            min-width: 300px;
            max-width: 500px;
        `;
        
        notification.innerHTML = `
            <div class="d-flex align-items-center">
                <i class="bi bi-${this.getIconForType(type)} me-2"></i>
                <span>${message}</span>
                <button type="button" class="btn-close ms-auto" data-bs-dismiss="alert"></button>
            </div>
        `;
        
        // 添加到页面
        document.body.appendChild(notification);
        
        // 自动移除
        if (duration > 0) {
            setTimeout(() => {
                if (notification.parentNode) {
                    notification.remove();
                }
            }, duration);
        }
        
        return notification;
    },
    
    /**
     * 根据类型获取图标
     */
    getIconForType: function(type) {
        const icons = {
            'success': 'check-circle',
            'danger': 'exclamation-triangle',
            'warning': 'exclamation-triangle',
            'info': 'info-circle',
            'primary': 'info-circle'
        };
        return icons[type] || 'info-circle';
    },
    
    /**
     * 确认对话框
     */
    confirm: function(message, title = '确认操作') {
        return new Promise((resolve) => {
            const result = window.confirm(`${title}\n\n${message}`);
            resolve(result);
        });
    },
    
    /**
     * 格式化日期时间
     */
    formatDateTime: function(dateString) {
        if (!dateString) return '';
        
        const date = new Date(dateString);
        if (isNaN(date.getTime())) return dateString;
        
        return date.toLocaleString('zh-CN', {
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit',
            second: '2-digit'
        });
    },
    
    /**
     * 格式化文件大小
     */
    formatFileSize: function(bytes) {
        if (bytes === 0) return '0 B';
        
        const k = 1024;
        const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    },
    
    /**
     * HTML转义
     */
    escapeHtml: function(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    },
    
    /**
     * 防抖函数
     */
    debounce: function(func, wait, immediate) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                timeout = null;
                if (!immediate) func.apply(this, args);
            };
            const callNow = immediate && !timeout;
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
            if (callNow) func.apply(this, args);
        };
    },
    
    /**
     * 节流函数
     */
    throttle: function(func, limit) {
        let inThrottle;
        return function() {
            const args = arguments;
            const context = this;
            if (!inThrottle) {
                func.apply(context, args);
                inThrottle = true;
                setTimeout(() => inThrottle = false, limit);
            }
        };
    },
    
    /**
     * 深度克隆对象
     */
    deepClone: function(obj) {
        if (obj === null || typeof obj !== 'object') return obj;
        if (obj instanceof Date) return new Date(obj.getTime());
        if (obj instanceof Array) return obj.map(item => this.deepClone(item));
        if (typeof obj === 'object') {
            const clonedObj = {};
            for (const key in obj) {
                if (obj.hasOwnProperty(key)) {
                    clonedObj[key] = this.deepClone(obj[key]);
                }
            }
            return clonedObj;
        }
    },
    
    /**
     * 生成UUID
     */
    generateUUID: function() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            const r = Math.random() * 16 | 0;
            const v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    },
    
    /**
     * 验证邮箱格式
     */
    isValidEmail: function(email) {
        const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return regex.test(email);
    },
    
    /**
     * 验证URL格式
     */
    isValidUrl: function(url) {
        try {
            new URL(url);
            return true;
        } catch (e) {
            return false;
        }
    },
    
    /**
     * 获取查询参数
     */
    getQueryParam: function(name) {
        const urlParams = new URLSearchParams(window.location.search);
        return urlParams.get(name);
    },
    
    /**
     * 设置查询参数
     */
    setQueryParam: function(name, value) {
        const url = new URL(window.location);
        url.searchParams.set(name, value);
        window.history.replaceState({}, '', url);
    },
    
    /**
     * 删除查询参数
     */
    removeQueryParam: function(name) {
        const url = new URL(window.location);
        url.searchParams.delete(name);
        window.history.replaceState({}, '', url);
    },
    
    /**
     * 复制文本到剪贴板
     */
    copyToClipboard: function(text) {
        return navigator.clipboard.writeText(text).then(() => {
            this.showNotification('已复制到剪贴板', 'success');
            return true;
        }).catch(err => {
            console.error('复制失败:', err);
            this.showNotification('复制失败', 'danger');
            return false;
        });
    },
    
    /**
     * 下载文件
     */
    downloadFile: function(content, filename, contentType = 'text/plain') {
        const blob = new Blob([content], { type: contentType });
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        window.URL.revokeObjectURL(url);
    }
};

/**
 * API请求工具
 */
window.PGMApi = {
    
    /**
     * 发送GET请求
     */
    get: function(url, params = {}) {
        const searchParams = new URLSearchParams(params);
        const fullUrl = searchParams.toString() ? `${url}?${searchParams}` : url;
        
        return fetch(fullUrl, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json'
            }
        }).then(this.handleResponse);
    },
    
    /**
     * 发送POST请求
     */
    post: function(url, data = {}) {
        return fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        }).then(this.handleResponse);
    },
    
    /**
     * 发送PUT请求
     */
    put: function(url, data = {}) {
        return fetch(url, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        }).then(this.handleResponse);
    },
    
    /**
     * 发送DELETE请求
     */
    delete: function(url) {
        return fetch(url, {
            method: 'DELETE',
            headers: {
                'Content-Type': 'application/json'
            }
        }).then(this.handleResponse);
    },
    
    /**
     * 处理响应
     */
    handleResponse: function(response) {
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        return response.json();
    }
};

/**
 * 表格工具
 */
window.PGMTable = {
    
    /**
     * 渲染分页
     */
    renderPagination: function(container, currentPage, totalPages, onPageChange) {
        const pagination = document.querySelector(container);
        if (!pagination) return;
        
        pagination.innerHTML = '';
        
        if (totalPages <= 1) return;
        
        // 上一页
        if (currentPage > 1) {
            const prevBtn = this.createPageButton('上一页', () => onPageChange(currentPage - 1));
            pagination.appendChild(prevBtn);
        }
        
        // 页码按钮
        const startPage = Math.max(1, currentPage - 2);
        const endPage = Math.min(totalPages, currentPage + 2);
        
        for (let i = startPage; i <= endPage; i++) {
            const isActive = i === currentPage;
            const pageBtn = this.createPageButton(i.toString(), () => onPageChange(i), isActive);
            pagination.appendChild(pageBtn);
        }
        
        // 下一页
        if (currentPage < totalPages) {
            const nextBtn = this.createPageButton('下一页', () => onPageChange(currentPage + 1));
            pagination.appendChild(nextBtn);
        }
    },
    
    /**
     * 创建分页按钮
     */
    createPageButton: function(text, onClick, isActive = false) {
        const li = document.createElement('li');
        li.className = `page-item ${isActive ? 'active' : ''}`;
        
        const a = document.createElement('a');
        a.className = 'page-link';
        a.href = '#';
        a.textContent = text;
        a.addEventListener('click', (e) => {
            e.preventDefault();
            onClick();
        });
        
        li.appendChild(a);
        return li;
    },
    
    /**
     * 排序表格
     */
    sortTable: function(table, columnIndex, ascending = true) {
        const tbody = table.querySelector('tbody');
        const rows = Array.from(tbody.querySelectorAll('tr'));
        
        rows.sort((a, b) => {
            const aText = a.cells[columnIndex].textContent.trim();
            const bText = b.cells[columnIndex].textContent.trim();
            
            // 尝试数字比较
            const aNum = parseFloat(aText);
            const bNum = parseFloat(bText);
            
            if (!isNaN(aNum) && !isNaN(bNum)) {
                return ascending ? aNum - bNum : bNum - aNum;
            }
            
            // 字符串比较
            return ascending ? aText.localeCompare(bText) : bText.localeCompare(aText);
        });
        
        // 重新插入排序后的行
        rows.forEach(row => tbody.appendChild(row));
    }
};

/**
 * 表单工具
 */
window.PGMForm = {
    
    /**
     * 序列化表单数据
     */
    serialize: function(form) {
        const formData = new FormData(form);
        const data = {};
        
        for (let [key, value] of formData.entries()) {
            if (data[key]) {
                // 处理多选值
                if (Array.isArray(data[key])) {
                    data[key].push(value);
                } else {
                    data[key] = [data[key], value];
                }
            } else {
                data[key] = value;
            }
        }
        
        return data;
    },
    
    /**
     * 验证表单
     */
    validate: function(form) {
        const errors = [];
        const requiredFields = form.querySelectorAll('[required]');
        
        requiredFields.forEach(field => {
            if (!field.value.trim()) {
                errors.push(`${field.name || field.id} 是必填字段`);
                field.classList.add('is-invalid');
            } else {
                field.classList.remove('is-invalid');
            }
        });
        
        // 邮箱验证
        const emailFields = form.querySelectorAll('input[type="email"]');
        emailFields.forEach(field => {
            if (field.value && !PGMUtils.isValidEmail(field.value)) {
                errors.push(`${field.name || field.id} 邮箱格式不正确`);
                field.classList.add('is-invalid');
            }
        });
        
        return {
            isValid: errors.length === 0,
            errors: errors
        };
    },
    
    /**
     * 重置表单验证状态
     */
    resetValidation: function(form) {
        const fields = form.querySelectorAll('.is-invalid');
        fields.forEach(field => field.classList.remove('is-invalid'));
    }
};

// 页面加载完成后的初始化
document.addEventListener('DOMContentLoaded', function() {
    // 初始化工具提示
    const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
    tooltipTriggerList.map(function (tooltipTriggerEl) {
        return new bootstrap.Tooltip(tooltipTriggerEl);
    });
    
    // 初始化弹出框
    const popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
    popoverTriggerList.map(function (popoverTriggerEl) {
        return new bootstrap.Popover(popoverTriggerEl);
    });
    
    // 添加全局错误处理
    window.addEventListener('error', function(event) {
        console.error('全局错误:', event.error);
        PGMUtils.showNotification('发生未知错误，请刷新页面重试', 'danger', 5000);
    });
    
    // 添加全局未处理的Promise拒绝处理
    window.addEventListener('unhandledrejection', function(event) {
        console.error('未处理的Promise拒绝:', event.reason);
        PGMUtils.showNotification('请求失败，请检查网络连接', 'danger', 5000);
    });
});

// 导出到全局
window.showSuccess = function(message) {
    PGMUtils.showNotification(message, 'success');
};

window.showError = function(message) {
    PGMUtils.showNotification(message, 'danger');
};

window.showWarning = function(message) {
    PGMUtils.showNotification(message, 'warning');
};

window.showInfo = function(message) {
    PGMUtils.showNotification(message, 'info');
};